from graphviz import Digraph


def generate_chinese_uml():
    # 创建有向图
    dot = Digraph(comment='新一代POS系统UML图',
                  graph_attr={'rankdir': 'TB', 'splines': 'ortho'},
                  node_attr={'fontname': 'Microsoft YaHei'})  # 设置中文字体

    # 参与者集群
    with dot.subgraph(name='cluster_actors') as actors:
        actors.attr(label='参与者', style='rounded,filled', color='lightblue', fontname='Microsoft YaHei')
        actors.node('顾客', '顾客', shape='ellipse', style='filled', fillcolor='lightblue')
        actors.node('收银员', '收银员', shape='ellipse', style='filled', fillcolor='lightblue')
        actors.node('系统管理员', '系统管理员', shape='ellipse', style='filled', fillcolor='lightblue')

    # 核心销售流程
    with dot.subgraph(name='cluster_core_process') as core:
        core.attr(label='核心销售流程', color='darkgreen', fontname='Microsoft YaHei')
        core.node('扫描商品', '扫描商品\n(记录商品信息)', shape='rectangle', style='filled', fillcolor='palegreen')
        core.node('显示金额', '显示累计金额\n(实时更新明细)', shape='rectangle', style='filled', fillcolor='palegreen')
        core.node('处理支付', '处理支付\n(验证支付信息)', shape='rectangle', style='filled', fillcolor='palegreen')
        core.node('更新库存', '更新库存\n(减少库存数量)', shape='rectangle', style='filled', fillcolor='palegreen')
        core.node('生成小票', '生成购物小票\n(电子/纸质)', shape='rectangle', style='filled', fillcolor='palegreen')

        # 连接核心流程
        core.edges([
            ('扫描商品', '显示金额'),
            ('显示金额', '处理支付'),
            ('处理支付', '更新库存'),
            ('更新库存', '生成小票')
        ])

    # 系统功能集群
    with dot.subgraph(name='cluster_features') as features:
        features.attr(label='系统功能', color='darkred', fontname='Microsoft YaHei')

        # 业务灵活性
        features.node('规则引擎', '自定义规则引擎\n(嵌入合规性校验)', shape='rectangle', style='filled',
                      fillcolor='mistyrose')
        features.node('定价策略', '动态定价策略\n(会员折扣/满减促销)', shape='rectangle', style='filled',
                      fillcolor='mistyrose')

        # 系统健壮性
        features.node('离线模式', '离线容灾处理\n(加密缓存交易数据)', shape='rectangle', style='filled',
                      fillcolor='lightcyan')
        features.node('数据同步', '网络恢复后\n自动云端同步', shape='rectangle', style='filled', fillcolor='lightcyan')
        features.node('异常恢复', '异常状态恢复\n(事务日志断点续传)', shape='rectangle', style='filled',
                      fillcolor='lightcyan')

        # 多终端支持
        features.node('多端适配', '多终端设备支持\n(Web/Swing/触摸屏/PDA)', shape='rectangle', style='filled',
                      fillcolor='lavender')

        # 第三方集成
        features.node('API集成', '第三方系统集成\n(库存/税务/财务)', shape='rectangle', style='filled',
                      fillcolor='wheat')
        features.node('支付方式', '混合支付支持\n(现金/银行卡/扫码/NFC/积分)', shape='rectangle', style='filled',
                      fillcolor='wheat')

        # 硬件监控
        features.node('硬件监控', '硬件状态监控\n(打印机缺纸警报)', shape='rectangle', style='filled',
                      fillcolor='peachpuff')

    # 异常处理集群
    with dot.subgraph(name='cluster_exceptions') as exceptions:
        exceptions.attr(label='异常处理机制', color='purple', fontname='Microsoft YaHei')
        exceptions.node('自动回滚', '支付失败时\n自动库存回滚', shape='rectangle', style='filled', fillcolor='thistle')
        exceptions.node('订单修改', '订单修改/撤销\n(限时操作)', shape='rectangle', style='filled', fillcolor='thistle')
        exceptions.node('硬件警报', '硬件故障时\n多级警报系统', shape='rectangle', style='filled', fillcolor='thistle')

    # POS系统边界
    with dot.subgraph(name='cluster_system') as system:
        system.attr(label='新一代POS系统', style='dashed,bold', color='blue', fontname='Microsoft YaHei')
        system.node('POS系统', 'POS核心系统', shape='component', style='filled', fillcolor='lightgrey')

    # 连接参与者到用例
    dot.edges([
        ('顾客', '扫描商品'),
        ('收银员', '扫描商品'),
        ('顾客', '处理支付'),
        ('收银员', '订单修改'),
        ('系统管理员', '规则引擎'),
        ('系统管理员', '定价策略')
    ])

    # 连接功能到系统
    dot.edges([
        ('规则引擎', 'POS系统'),
        ('定价策略', 'POS系统'),
        ('离线模式', 'POS系统'),
        ('数据同步', 'POS系统'),
        ('多端适配', 'POS系统'),
        ('API集成', 'POS系统'),
        ('支付方式', 'POS系统'),
        ('硬件监控', 'POS系统')
    ])

    # 连接异常处理
    dot.edges([
        ('处理支付', '自动回滚'),
        ('自动回滚', '订单修改'),
        ('硬件监控', '硬件警报')
    ])

    # 添加需求注释
    dot.node('需求说明',
             '核心需求说明：\n'
             '1. 业务灵活性：支持自定义规则和定价策略\n'
             '2. 系统健壮性：离线操作+自动恢复机制\n'
             '3. 多终端适配：统一交互协议\n'
             '4. 异常处理：熔断机制+硬件监控',
             shape='note', style='filled', fillcolor='lemonchiffon', fontname='Microsoft YaHei')
    dot.edge('需求说明', 'POS系统', style='invis')

    # 渲染图表（移除encoding参数）
    dot.render('pos_system_uml', view=True, format='png')


if __name__ == '__main__':
    generate_chinese_uml()